package com.ketai.itripauth.services.impl;

import cn.hutool.core.util.ReUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ketai.bo.UserBO;
import com.ketai.commom.ErrorCodeEnum;
import com.ketai.commom.R;
import com.ketai.commom.exception.ServiceException;
import com.ketai.itripauth.services.UserService;
import com.ketai.mapper.ItripUserMapper;
import com.ketai.pojo.ItripUser;
import com.ketai.tool.ActiveCode;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import java.util.UUID;

/**
 * @Author:长沙科泰梦想学院
 * @Description:
 * @Date:Create In 2021/12/18 15:21
 **/
@Service
public class UserServiceImpl extends ServiceImpl<ItripUserMapper, ItripUser> implements UserService {


    @Resource
    private MailService mailService;

    @Resource
    private RedisTemplate<String,String> RedisTemplate;

    @Value("${context.url}")
    private String url;

    @Override
    public ItripUser checkUser (String userName) {

        if (!StringUtils.hasLength(userName)) {
            //参数为空
            throw new ServiceException(ErrorCodeEnum.AUTH_PARAMETER_IS_EMPTY);
        }
        QueryWrapper<ItripUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_code", userName);
        ItripUser user = this.getOne(queryWrapper);
        return user;
    }

    @Override
    public ItripUser registerUser (UserBO bo) {
        if (!StringUtils.hasLength(bo.getUserCode())) {
            //参数为空
            throw new ServiceException(ErrorCodeEnum.AUTH_PARAMETER_IS_EMPTY);
        } else if (!StringUtils.hasLength(bo.getUserCode())) {
            throw new ServiceException(ErrorCodeEnum.AUTH_PARAMETER_ERROR);
        } else if (!StringUtils.hasLength(bo.getUserName())) {
            // 用户名为空
            throw new ServiceException(ErrorCodeEnum.AUTH_PARAMETER_IS_EMPTY);
        }
        // 邮箱有限验证 TODO
        /**
         *  @之前必须有内容且只能是字母（大小写）、数字、下划线(_)、减号（-）、点（.）
         * @和最后一个点（.）之间必须有内容且只能是字母（大小写）、数字、点（.）、减号（-），且两个点不能挨着
         * 最后一个点（.）之后必须有内容且内容只能是字母（大小写）、数字且长度为大于等于2个字节，小于等于6个字节
         */
        String reg = "^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*\\.[a-zA-Z0-9]{2,6}$";
        boolean isok = ReUtil.isMatch(reg, bo.getUserCode());
        if (!isok) {
            throw new ServiceException(ErrorCodeEnum.AUTH_ILLEGAL_USERCODE);
        }
        // 验证邮箱是否存在  TODO
        ItripUser user1 = checkUser(bo.getUserCode());
        if (user1 != null) {
            // 验证邮箱是否激活
            // 1 已激活
            if (user1.getActivated() == 1) {
                //帐号已存在
                throw new ServiceException(ErrorCodeEnum.AUTH_USER_ALREADY_EXISTS);
            }
            // 激活邮箱
            // 调用发送邮件的方法
            // 生成激活码  发送激活邮件
            String activationCode = UUID.randomUUID().toString();
            // 把激活码存入redis中  TODO
            RedisTemplate.opsForValue().set(user1.getUserCode(), activationCode, 30 * 60);
            sendMail(user1.getUserCode(), ActiveCode.MakeCode(user1.getUserCode(), activationCode, url));
            return null;
        }

        // 对密码进行加密
        String md5Password = SecureUtil.md5(bo.getUserPassword());
        // 给用户对象属性重新赋值
        bo.setUserPassword(md5Password);
        ItripUser user = new ItripUser();
        BeanUtils.copyProperties(bo, user);
        baseMapper.insert(user);

        // 生成一个激活码  TODO
        String activationCode = UUID.randomUUID().toString();
        sendMail(user1.getUserCode(), ActiveCode.MakeCode(user.getUserCode(), activationCode, url));
        // 把激活码存入redis中  TODO
        RedisTemplate.opsForValue().set(user.getUserCode(), activationCode, 30 * 60);
        return user;
    }

    @Override
    public boolean verify (String userCode, String activeCode) {
        System.out.println(RedisTemplate.hasKey(userCode));

        if (!RedisTemplate.hasKey(userCode)) {
            throw new ServiceException(ErrorCodeEnum.AUTH_PARAMETER_OUTTIME);
        }
        String code = RedisTemplate.opsForValue().get(userCode);
        if (activeCode.trim().equals(code.trim())) {
            // 根据邮箱获取 对象
            UpdateWrapper wrapper = new UpdateWrapper();
            wrapper.eq("user_code", userCode);
            wrapper.set("activated",1);
            this.update(wrapper);
            return  true;
        }
        throw new ServiceException(ErrorCodeEnum.AUTH_PARAMETER_OUTTIME);

    }


    public void sendMail (String to, String content) {
        String subject = "帐号激活";
        try {
            mailService.sendHtmlMail(to, subject, content);
        } catch (MessagingException e) {
            e.printStackTrace();
            throw new ServiceException(ErrorCodeEnum.AUTH_ACTIVATE_FAILED);

        }

    }
}
